package com.xframework.security.filter;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.xframework.exception.BusinessException;
import com.xframework.redis.XRedisTemplate;
import io.jsonwebtoken.Claims;

import com.xframework.security.model.SecurityAccount;
import com.xframework.security.util.Constant;
import com.xframework.security.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SecurityFilter implements Filter {
    @Autowired
    private XRedisTemplate xRedisTemplate;

    public SecurityFilter() {
        System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx SecurityFilter xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String url = httpRequest.getServletPath();
        System.out.println("我被过滤啦" + url);
        boolean flag = Boolean.FALSE;
        //跳过不需要验证的路径
        if (Constant.securityExcludeUrlPatterns != null) {
            for (String regex : Constant.securityExcludeUrlPatterns) {
                if (Constant.matches(regex, url)) {
                    flag = Boolean.TRUE;
                    break;
                }
            }
        }
        if (!flag) {
            //统一鉴权逻辑
            String securityToken = httpRequest.getHeader(Constant.Authorization);
            if (securityToken != null) {
                Claims payload = JWTUtil.parserJWT(securityToken);
                if (payload != null) {
                    String applicationId = payload.getSubject();
                    String accountId = payload.getId();
                    String securityAccountJson = xRedisTemplate.get(Constant.SECURITY_ACCOUNT + Constant.UNDERLINE + applicationId + Constant.UNDERLINE + accountId, Constant.securityJwtExpiration);
                    SecurityAccount securityAccount = JSON.parseObject(securityAccountJson, SecurityAccount.class);
                    if (Constant.securityJwtDelay) {
                        securityAccount.setAccountId(accountId);
                        securityAccount.setAccountName(payload.getAudience());
                        securityAccount.setApplicationId(applicationId);
                        securityToken = JWTUtil.createJWT(securityAccount);
                    }
                    String resourceUrls = securityAccount.getResourceUrls();
                    if (Constant.matches(resourceUrls, url)) {
                        flag = Boolean.TRUE;
                        httpResponse.setHeader(Constant.ACCESS_CONTROL_EXPOSE_HEADERS, Constant.Authorization);
                        httpResponse.setHeader(Constant.Authorization, securityToken);
                        httpResponse.setHeader(Constant.SECURITY_ACCOUNT, accountId);
                    }
                }
            }
        }
        if (flag) {
            filterChain.doFilter(httpRequest, httpResponse);
        } else {
//            RespData respData = new RespData(0, "认证身份已过期");
//            String json = JSON.toJSONString(respData);
//            OutputStream out = httpResponse.getOutputStream();
//            out.write(json.getBytes(StandardCharsets.UTF_8.name()));
//            out.flush();
//        httpResponse.setContentType(Constant.CONTENT_TYPE_HTML);
//            httpResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
//            httpResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
            throw new BusinessException(Constant.securityInvalidMessage);
        }
    }

}
